import Immutable, {List, Map, fromJS} from 'immutable';
import {expect} from 'chai';
import {setEntries, next, vote} from '../src/core';

const E1 = 'Trainspotting';
const E2 = '28 Days Later';
const E3 = 'Sunshine';
const E4 = 'Millions';
const E5 = '127 Hours';

describe('application logic', ()=> {
    describe('setEntries', ()=> {
        it('adds the entries to the state', ()=> {
            const state = Map();
            const entries = List.of(E1, E2);
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of(E1, E2)
            }));
        });

        it('converts to immutable', ()=> {
            const state = Map();
            const entries = [E1, E2];
            const nextState = setEntries(state, entries);
            expect(nextState).to.equal(Map({
                entries: List.of(E1, E2)
            }));
        });
    });
    describe('next', ()=> {
        it('takes the next two entries under vote', ()=> {
            const state = Immutable.fromJS({
                entries: [E1, E2, E3]
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of(E1, E2)
                }),
                entries: List.of(E3)
            }))
        });
    });
    describe('vote', ()=> {
        /*it('creates a tally for the voted entry', ()=> {
            const state = Immutable.fromJS({
                vote: {
                    pair: [E1, E2]
                },
                entries: []
            });
            const nextState = vote(state, E1);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of(E1, E2),
                    tally: Map({
                        [E1]: 1
                    })
                }),
                entries: List()
            }));
        });
        it('adds to existing tally for the voted entry', ()=> {
            const state = Immutable.fromJS({
                vote: {
                    pair: [E1, E2],
                    tally: {
                        [E1]: 3,
                        [E2]: 2
                    }
                },
                entries: []
            });
            const nextState = vote(state, E1);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of(E1, E2),
                    tally: Map({
                        [E1]: 4,
                        [E2]: 2
                    })
                }),
                entries: List()
            }));
        });*/
        it('puts winner of current vote back to entries', ()=> {
            const state = Immutable.fromJS({
                vote: {
                    pair: [E1, E2],
                    tally: {
                        [E1]: 4,
                        [E2]: 2
                    }
                },
                entries: [E3, E4, E5]
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of(E3, E4)
                }),
                entries: List.of(E5, E1)
            }))
        });
        it('puts both from tied vote back to entries', ()=> {
            const state = Immutable.fromJS({
                vote: {
                    pair: [E1, E2],
                    tally: {
                        [E1]: 3,
                        [E2]: 3
                    }
                },
                entries: [E3, E4, E5]
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                vote: Map({
                    pair: List.of(E3, E4)
                }),
                entries: List.of(E5, E1, E2)
            }));
        });
        it('marks winner when just one entry left', ()=> {
            const state = Immutable.fromJS({
                vote: {
                    pair: [E1, E2],
                    tally: {
                        [E1]: 4,
                        [E2]: 2
                    }
                },
                entries: []
            });
            const nextState = next(state);
            expect(nextState).to.equal(Map({
                winner: E1
            }));
        });
        it('creates a tally for the voted entry', ()=> {
            const state = fromJS({
                pair: [E1, E2]
            });
            const nextState = vote(state, E1);
            expect(nextState).to.equal(fromJS({
                pair: [E1, E2],
                tally: {
                    [E1]: 1
                }
            }));
        });
        it('adds to existing tally for the voted entry', ()=> {
            const state = fromJS({
                pair: [E1, E2],
                tally: {
                    [E1]: 3,
                    [E2]: 2
                }
            });
            const nextState = vote(state, E1);
            expect(nextState).to.equal(fromJS({
                pair: [E1, E2],
                tally: {
                    [E1]: 4,
                    [E2]: 2
                }
            }));
        });
    })
});